package com.alibaba.druid.pool;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.beanutils.BeanUtils;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Environment;
import org.hibernate.connection.ConnectionProvider;

/**
 * let hibernate support druid pool in hibernate.cfg.xml
 * 
 * @author xwz
 */
public class DruidDatasourceConnectionProvider implements ConnectionProvider {
	private static final String DRUID_PREFIX = "druid.";

	private DataSource ds;
	private String user;
	private String pass;

	public DataSource getDataSource() {
		return ds;
	}

	public void setDataSource(DataSource ds) {
		this.ds = ds;
	}

	public void configure(Properties props) throws HibernateException {
		user = props.getProperty(Environment.USER);
		pass = props.getProperty(Environment.PASS);

		DruidDataSource dataSource = new DruidDataSource();
		// setDefault
		dataSource.setInitialSize(3);
		dataSource.setTimeBetweenConnectErrorMillis(1000);
		dataSource.setDefaultAutoCommit(true);
		dataSource.setLogAbandoned(false);
		dataSource.setMaxActive(15);
		dataSource.setMinIdle(3);
		dataSource.setTestOnReturn(false);
		dataSource.setTestOnBorrow(false);

		for (Object keyObj : props.keySet()) {
			String key = String.valueOf(keyObj);
			if (key.startsWith(DRUID_PREFIX)) {
				String propName = key.substring(DRUID_PREFIX.length());
				String value = props.getProperty(key);
				try {
					BeanUtils.setProperty(dataSource, propName, value);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		setDataSource(dataSource);
	}

	public Connection getConnection() throws SQLException {
		if (user != null || pass != null) {
			return ds.getConnection(user, pass);
		} else {
			return ds.getConnection();
		}
	}

	public void closeConnection(Connection conn) throws SQLException {
		conn.close();
	}

	public void close() {
	}

	/**
	 * @see ConnectionProvider#supportsAggressiveRelease()
	 */
	public boolean supportsAggressiveRelease() {
		return true;
	}

}
